/**
 *  Copyright 2010 Kyle O'Connor, Justin Arling, Mike Mercieca
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package edu.drexel.sd0910.ece01.aqmon.gui.wizard;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;

/**
 * The model for the Wizard component, which tracks the text and enabled state
 * of each of the buttons as well as the current panel that is displayed.
 * 
 * @author Kyle O'Connor
 * 
 */
public class WizardModel {

	/**
	 * Identification string for the current panel.
	 */
	public static final String CURRENT_PANEL_DESCRIPTOR_PROPERTY = "currentPanelDescriptorProperty";

	/**
	 * Property identification String for the Back button's text
	 */
	public static final String BACK_BUTTON_TEXT_PROPERTY = "backButtonTextProperty";
	/**
	 * Property identification String for the Back button's icon
	 */
	public static final String BACK_BUTTON_ICON_PROPERTY = "backButtonIconProperty";
	/**
	 * Property identification String for the Back button's enabled state
	 */
	public static final String BACK_BUTTON_ENABLED_PROPERTY = "backButtonEnabledProperty";

	/**
	 * Property identification String for the Next button's text
	 */
	public static final String NEXT_FINISH_BUTTON_TEXT_PROPERTY = "nextButtonTextProperty";
	/**
	 * Property identification String for the Next button's icon
	 */
	public static final String NEXT_FINISH_BUTTON_ICON_PROPERTY = "nextButtonIconProperty";
	/**
	 * Property identification String for the Next button's enabled state
	 */
	public static final String NEXT_FINISH_BUTTON_ENABLED_PROPERTY = "nextButtonEnabledProperty";

	/**
	 * Property identification String for the Cancel button's text
	 */
	public static final String CANCEL_BUTTON_TEXT_PROPERTY = "cancelButtonTextProperty";
	/**
	 * Property identification String for the Cancel button's icon
	 */
	public static final String CANCEL_BUTTON_ICON_PROPERTY = "cancelButtonIconProperty";
	/**
	 * Property identification String for the Cancel button's enabled state
	 */
	public static final String CANCEL_BUTTON_ENABLED_PROPERTY = "cancelButtonEnabledProperty";

	private WizardPanelDescriptor currentPanel;

	private HashMap<Object, WizardPanelDescriptor> panelHashmap;
	private HashMap<String, String> buttonTextHashmap;
	private HashMap<String, Boolean> buttonEnabledHashmap;

	private PropertyChangeSupport propertyChangeSupport;

	/**
	 * Default constructor.
	 */
	public WizardModel() {
		panelHashmap = new HashMap<Object, WizardPanelDescriptor>();
		buttonTextHashmap = new HashMap<String, String>();
		buttonEnabledHashmap = new HashMap<String, Boolean>();

		propertyChangeSupport = new PropertyChangeSupport(this);
	}

	public WizardPanelDescriptor getCurrentPanelDescriptor() {
		return currentPanel;
	}

	public void registerPanel(Object id, WizardPanelDescriptor des) {
		panelHashmap.put(id, des);
	}

	public boolean setCurrentPanel(Object id) {
		// First, get the hashtable reference to the panel that should
		// be displayed.

		WizardPanelDescriptor nextPanel = panelHashmap.get(id);

		// If we couldn't find the panel that should be displayed, return
		// false.

		if (nextPanel == null)
			throw new WizardPanelNotFoundException();

		WizardPanelDescriptor oldPanel = currentPanel;
		currentPanel = nextPanel;

		if (oldPanel != currentPanel)
			firePropertyChange(CURRENT_PANEL_DESCRIPTOR_PROPERTY, oldPanel, currentPanel);

		return true;
	}

	public String getBackButtonText() {
		return buttonTextHashmap.get(BACK_BUTTON_TEXT_PROPERTY);
	}

	void setBackButtonText(String newText) {
		Object oldText = getBackButtonText();
		if (!newText.equals(oldText)) {
			buttonTextHashmap.put(BACK_BUTTON_TEXT_PROPERTY, newText);
			firePropertyChange(BACK_BUTTON_TEXT_PROPERTY, oldText, newText);
		}
	}

	public String getNextFinishButtonText() {
		return buttonTextHashmap.get(NEXT_FINISH_BUTTON_TEXT_PROPERTY);
	}

	void setNextFinishButtonText(String newText) {
		Object oldText = getNextFinishButtonText();
		if (!newText.equals(oldText)) {
			buttonTextHashmap.put(NEXT_FINISH_BUTTON_TEXT_PROPERTY, newText);
			firePropertyChange(NEXT_FINISH_BUTTON_TEXT_PROPERTY, oldText, newText);
		}
	}

	public String getCancelButtonText() {
		return buttonTextHashmap.get(CANCEL_BUTTON_TEXT_PROPERTY);
	}

	void setCancelButtonText(String newText) {
		Object oldText = getCancelButtonText();
		if (!newText.equals(oldText)) {
			buttonTextHashmap.put(CANCEL_BUTTON_TEXT_PROPERTY, newText);
			firePropertyChange(CANCEL_BUTTON_TEXT_PROPERTY, oldText, newText);
		}
	}

	public Boolean getBackButtonEnabled() {
		return buttonEnabledHashmap.get(BACK_BUTTON_ENABLED_PROPERTY);
	}

	void setBackButtonEnabled(Boolean newValue) {
		Boolean oldValue = getBackButtonEnabled();
		if (newValue != oldValue) {
			buttonEnabledHashmap.put(BACK_BUTTON_ENABLED_PROPERTY, newValue);
			firePropertyChange(BACK_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
		}
	}

	public Boolean getNextFinishButtonEnabled() {
		return buttonEnabledHashmap.get(NEXT_FINISH_BUTTON_ENABLED_PROPERTY);
	}

	void setNextFinishButtonEnabled(Boolean newValue) {
		Boolean oldValue = getNextFinishButtonEnabled();
		if (newValue != oldValue) {
			buttonEnabledHashmap.put(NEXT_FINISH_BUTTON_ENABLED_PROPERTY, newValue);
			firePropertyChange(NEXT_FINISH_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
		}
	}

	public Boolean getCancelButtonEnabled() {
		return buttonEnabledHashmap.get(CANCEL_BUTTON_ENABLED_PROPERTY);
	}

	void setCancelButtonEnabled(Boolean newValue) {
		Boolean oldValue = getCancelButtonEnabled();
		if (newValue != oldValue) {
			buttonEnabledHashmap.put(CANCEL_BUTTON_ENABLED_PROPERTY, newValue);
			firePropertyChange(CANCEL_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
		}
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		propertyChangeSupport.addPropertyChangeListener(listener);
	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		propertyChangeSupport.removePropertyChangeListener(listener);
	}

	protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
		propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
	}

}
